package com.stox.client.ui.javafx.watchlist.application;

import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.stereotype.Component;

import com.stox.client.api.watchlist.event.WatchlistEntryAddedEvent;
import com.stox.client.core.application.AbstractApplication;
import com.stox.client.ui.javafx.watchlist.view.WatchlistView;
import com.stox.client.ui.javafx.widget.ContextMenuConfigurerRegistry;
import com.stox.shared.i18n.MessageSource;
import com.stox.shared.util.Constant;

@Component
public class WatchlistApplication extends AbstractApplication implements SmartApplicationListener, DisposableBean{
	private static final long DELAY = 1000*5;
	
	private WatchlistView watchlistView;
	
	private static class WatchlistEntryRefreshTimerTask extends TimerTask{
		
		private static final List<WatchlistEntryRefreshTimerTask> list = new ArrayList<>();
		
		private final WatchlistApplication watchlistApplication;
		
		public WatchlistEntryRefreshTimerTask(WatchlistApplication watchlistApplication) {
			this.watchlistApplication = watchlistApplication;
			list.add(this);
		}
		
		@Override
		public void run() {
			WatchlistView watchlistView = watchlistApplication.watchlistView;
			if(null != watchlistView && null != watchlistView.getWatchlistEntryTableView()){
				watchlistView.getWatchlistEntryTableView().refresh();
			}
		}
		
		@Override
		public boolean cancel() {
			return super.cancel();
		}
		
		public static void cancel(WatchlistApplication watchlistApplication){
			WatchlistEntryRefreshTimerTask removable = null;
			for(WatchlistEntryRefreshTimerTask task : list){
				if(watchlistApplication.equals(task.watchlistApplication)){
					removable = task;
					break;
				}
			}
			removable.cancel();
			list.remove(removable);
		}
		
		public static void cancelAll(){
			for(WatchlistEntryRefreshTimerTask task : list){
				task.cancel();
			}
			list.clear();
		}
	};
	
	@Autowired
	private WatchlistContextMenuConfigurer watchlistContextMenuConfigurer;
	
	@Override
	public void destroy() throws Exception {
		WatchlistEntryRefreshTimerTask.cancelAll();
	}
	
	@Override
	public String getName() {
		return MessageSource.get("Watchlists");
	}
	
	@Override
	public void start() {
		super.start();
		ContextMenuConfigurerRegistry.getInstance().addContextMenuConfigurer(watchlistContextMenuConfigurer);
	}
	
	@Override
	public void stop() {
		super.stop();
		ContextMenuConfigurerRegistry.getInstance().removeContextMenuConfigurer(watchlistContextMenuConfigurer);
	}
	
	@Override
	public void show() {
		super.show();
		if(null == watchlistView){
			watchlistView = new WatchlistView();
		}
		watchlistView.open();
		Constant.timer.schedule(new WatchlistEntryRefreshTimerTask(this), 0, DELAY);
	}

	@Override
	public void hide() {
		super.hide();
		WatchlistEntryRefreshTimerTask.cancel(this);
		watchlistView.close();
	}
	
	@Override
	public int getOrder() {
		return 0;
	}
	
	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if(null != watchlistView){
			WatchlistEntryAddedEvent watchlistEntryAddedEvent = (WatchlistEntryAddedEvent)event;
			watchlistView.addWatchlistEntry(watchlistEntryAddedEvent.getWatchlistEntry());
		}
	}
	
	@Override
	public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
		return WatchlistEntryAddedEvent.class.isAssignableFrom(eventType);
	}
	
	@Override
	public boolean supportsSourceType(Class<?> sourceType) {
		return true;
	}
	
}
